package com.yumeng.common.auth;

import cn.hutool.core.map.MapUtil;
import com.yumeng.common.data.enums.AuthMode;
import com.yumeng.common.helper.StringHelper;

import java.io.Serializable;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * 认证信息基类，用于保存自定义数据
 *
 * @author wxd
 * @date 2024/7/22 下午4:18
 */
public abstract class BaseAuthInfo implements Serializable {

    /**
     * 行政区划编码KEY
     */
    public static final String DATA_KEY_REGION_CODE = "regionCode";

    /**
     * 身份标识（userId）
     * @return
     */
    public abstract String getIdentityId();
    /**
     * 身份名称（realName/nickname）
     *
     * @return
     */
    public abstract String getIdentityName();
    /**
     * 认证Key（username/phone/idcard等）
     *
     * @return
     */
    public abstract String getAuthKey();
    /**
     * 认证凭证（password）
     *
     * @return
     */
    public abstract String getCredentials();
    /**
     * 盐
     *
     * @return
     */
    public abstract String getSalt();
    /**
     * 用户类型
     *
     * @return
     */
    public abstract String getUserTypes();
    /**
     * 认证模式
     *
     * @return
     */
    public abstract AuthMode getAuthMode();
    /**
     * 是否可用
     *
     * @return
     */
    public abstract boolean isEnabled();
    /**
     * 账号是否被锁定
     *
     * @return
     */
    public abstract boolean isAccountLocked();
    /**
     * 账号是否过期
     *
     * @return
     */
    public abstract boolean isAccountExpired();
    /**
     * 凭证是否过期
     *
     * @return
     */
    public abstract boolean isCredentialsExpired();
    /**
     * 获取所有权限
     *
     * @return
     */
    public abstract Set<String> getAuthorities();
    /**
     * 擦除凭证
     * TODO SpringSecurity中使用，shiro中未使用，是否需要优化
     */
    public abstract void eraseCredentials();

    /**
     * 扩展信息（用户自定义）
     */
    private Map<String, Object> dataMap;
    /**
     * 认证信息，用于认证成功返回前端的数据（用户自定义）
     */
    private Map<String, Object> loginInfo;
    /**
     * 一些动态的、通用的其他标准信息
     * 250929 由于该属性是每次访问时动态赋值的，因此不参与缓存 和 比较
     */
    private transient CommAuthDetails details;


    public Map<String, Object> getDataMap() {
        return dataMap;
    }

    public void setDataMap(Map<String, Object> dataMap) {
        this.dataMap = dataMap;
    }

    public CommAuthDetails getDetails() {
        return details;
    }

    public void setDetails(CommAuthDetails details) {
        this.details = details;
    }

    public Map<String, Object> getLoginInfo() {
        return loginInfo;
    }

    public void setLoginInfo(Map<String, Object> loginInfo) {
        this.loginInfo = loginInfo;
    }

    @Override
    public boolean equals(Object o) {
        if (o == null || getClass() != o.getClass()) return false;
        BaseAuthInfo authInfo = (BaseAuthInfo) o;
        return Objects.equals(dataMap, authInfo.dataMap)
                && Objects.equals(loginInfo, authInfo.loginInfo);
                //&& Objects.equals(details, authInfo.details)
    }

    @Override
    public int hashCode() {
        return Objects.hash(dataMap, loginInfo);//, details
    }

    public <T> T getValue(String key, Class<T> type) {
        if (dataMap != null && !dataMap.isEmpty()) {
            return MapUtil.get(dataMap, key, type);
        }
        return null;
    }

    public Long getIdentityIdLongVal(){
        return Long.parseLong(getIdentityId());
    }

    public Boolean getSuperAdmin(){
        //TODO 暂时把userType=0定义为超级管理员
        return StringHelper.stringToList(getUserTypes()).contains("0");
    }

    public String getRegionCode(){
        return getValue(DATA_KEY_REGION_CODE,  String.class);
    }

    public boolean isAnon(){
        return false;
    }

    public boolean isUnKnown(){
        return false;
    }
}
